#!/usr/bin/env bash
# @TODO Add a prompt function that allows you to type the command name OR the number
# Something like: bent show: 1. history, 2. history full, 3. url
# Then you can type 1,2, or 3. OR you can type history, history full, or url
function prompt(){
# @TODO Integrate exiting by default so you'd just write `prompt "msg" arg || return`
# & Take a flag to disable printing of exit status
# @TODO fix output... When going to line 2, it just wraps back to the first line, clearing the prompt message
read -e -p "$(msg -n "${cCommand}${1}${cOff}") " ${2}
}
# Prompts a user & checks if user aborted the prompt
# Usage: prompt_quit "A MESSAGE" usersAnswer -e && return
# By default an empty message means QUIT=true
# -e is optional & indicates EMPTY message means QUIT=false
# where QUIT is the return value
function prompt_quit(){
local -n OUTPUT=$2
read -e -p "$(msg -n "${cCommand}${1}${cOff}${cInstruct} (q-quit)${cOff}") " OUTPUT
if [[ "$3" == "-e" && -z "$OUTPUT" ]];then
return 1
fi
prompt_exited "$OUTPUT" -p \
|| return 1;
return 0
}
function prompt_yes_or_quit(){
read -e -p "$(msg -n "${cCommand}${1}${cOff}${cInstruct} (y/no)${cOff}") " ANSWER
if [[ "$ANSWER" == "y" || "$ANSWER" == "Y" || "$ANSWER" == "yes" ]];then
return 1;
else
msg_status "'y' required. Exiting"
return 0;
fi
}
function prompt_yes_or_no(){
local answer;
prompt "$1 (y-yes/n-no): " response
yesFunc=$2;
noFunc=$3;
if [[ $response == "y" || $response == "Y" ]]; then
return 0
elif [[ $response == "n" || $response == "N" ]]; then
return 1;
fi
return 1;
}
prompt_enter(){
local answer;
prompt "$1 [enter to continue]" response
if [[ $response == "" ]]; then
return 0;
fi
return 1;
}
prompt_yesnotwo(){
local answer;
prompt "$1 (y-yes/n-no): " response
yesFunc=$2;
noFunc=$3;
if [[ $response == "y" || $response == "Y" ]]; then
return 0
elif [[ $response == "n" || $response == "N" ]]; then
return 1;
fi
return 1;
}
prompt_yesno(){
local answer;
prompt "$1 (y-yes/n-no): " response
yesFunc=$2;
noFunc=$3;
if [[ $response == "y" || $response == "Y" ]]; then
answer=0;
if [[ -n "$yesFunc" ]]; then
$yesFunc
fi
elif [[ $response == "n" || $response == "N" ]]; then
answer=1;
if [[ -n "$noFunc" ]]; then
$noFunc
fi
fi
return $answer;
}
prompt_yesno_bool(){
local answer;
prompt "$1 (y-yes/n-no): " response
local -n answer=${2}
if [[ $response == "y" || $response == "Y" ]]; then
answer=true;
elif [[ $response == "n" || $response == "N" ]]; then
answer=false;
fi
}
# To print the answer and return when quit, use [prompt_exited "$response" -p && return;]
# To simply return in your function without printing anything: [prompt_exited "$response" && return;]
# @TODO add flag for using empty as a cancel as well
prompt_exited(){
# @TODO add option to accept empty string (or possibly other "quit" responses
if [[ "$2" == "-p" ]]; then
shouldPrint=true;
else
shouldPrint=false;
fi;
case "$1" in
n|N)
$shouldPrint && msg_status "answered no"
return 0
;;
q|Q)
$shouldPrint && msg_status "quitting"
return 0
;;
c|C)
$shouldPrint && msg_status "canceled"
return 0
;;
"")
$shouldPrint && msg_status "needed answer"
return 0
;;
esac
return 1;
}
function prompt_choose_function(){
prompt_choose cmd "$@" \
&& $cmd
}
# Use like:
# prompt_choose choice
# "# header" \
# "'message" \
# "choice_1" "shorthand" "choice 1 description" \
# "choice_2" "shorthand 2" "choice 2 description" \
# ;
# echo "${choice}"
#
# prompt_choose returns true if choice successful, false otherwise.
# Allows usage like:
# prompt_choose cmd ... && $cmd;
# To choose a command from the list & execute it OR do nothing
#
# Shorthands are optional. If omitting, use empty string: "choice" "" "description"
function prompt_choose(){
## INIT variables
local -n output=$1
output=""
declare -a functions;
# To make it a base-1 array
functions+=("")
declare -A shorthands;
entryCount=0
shorthandCount=0
status=$open
stOpen=0
stFunction=1
stShorthand=2
# Print entries & headers
for str in "${@:2}"; do
charOne=${str:0:1}
if [[ $status -eq $stOpen && ${charOne} == "#" ]]; then
# display header
msg
header "${str:1}"
elif [[ $status -eq $stOpen && ${charOne} == "'" ]]; then
# display header
msg " ${str:1}"
elif [[ $status -eq $stOpen ]]; then
# store functions
entryCount=$(($entryCount + 1))
functions+=("${str}")
status=$stFunction
elif [[ $status -eq $stFunction ]]; then
# store shorthands
if [[ -z "$str" ]];then
has_shorthand=false
else
has_shorthand=true
prevShorthand="$str"
shorthandCount+=1;
shorthands["$str"]="$entryCount"
fi
status=$stShorthand
elif [[ $status -eq $stShorthand ]]; then
# display entry
shStr=""
if $has_shorthand;then
d=$(($entryCount + 1))
shStr="$(color_li $d)[$prevShorthand]${cOff} "
fi
msg " $(color_li $entryCount)${entryCount}.${cOff} ${shStr}${str}"
status=$stOpen
fi
done
has_shorthand=false;
if [[ $shorthandCount -gt 0 ]];then
has_shorthand=true
fi
# prompt for choice
msg
msg_instruct "(q-quit)"
$has_shorthand \
&& prompt "Type the [shorthand]\n or choose (1-${entryCount}):" answer \
|| prompt "Choose (1-${entryCount}):" answer
prompt_exited "$answer" -p && return 1;
# Determine function from answer
funcIndex="${shorthands[${answer}]}"
if [[ -z "$funcIndex" ]]; then
funcIndex="$answer"
fi
func="${functions[${funcIndex}]}"
# Display wrong answer message
if [[ -z "${func}" ]];then
shMsg=""
if $has_shorthand;then
shMsg="\n OR a [shorthand] (without the brackets)"
fi
msg_mistake "A number 1-${entryCount}${shMsg} is required.\nYou entered " \
"${num}" \
;
return 1;
fi;
# set output & return true
output="${func}"
return 0;
}